#pragma once
/**
 * @defgroup Core Basic solution libraries
 */

/**
 * \file
 * \ingroup Core
 * implementation file: File:cfdGrid.cpp
 * ---
 * Defines class cfdGrid which encapsulates common functionaliy
 * of finite difference grid.
*/
#include "MthParser.h"

/**
 * \ingroup Core
 * \brief finite-difference 2-d grid
 * A two-dimensional grid with some numerical methods and functionaity that
 * is commonly used in finite difference grids.
 * \author HapTork
*/

class cfdGrid{
public:
	/** Default Constructor: Definition
	 * ---
	 * Inline defaul ctor for a null grid
	 */

	cfdGrid(){body=NULL;x=y=0;}

	/** two parameter Constructor: Definition
	 * ---
	 * ctor for a new grid of (x X y) order, fills initial grid with all zeros

	 * @param x	mesh points in x direction including boundary
	 * @param y mesh points in y direction including boundary
	 */

	cfdGrid(int x,int y);

	/** Copy Constructor: Definition
	 * ---
	 * Copies all the grid data to destination grid

	 * @param o destination object reference
	 */
	cfdGrid( const cfdGrid &o );

	/** Assignment Operator Overload: Definition
	 * ---
	 * Copies all the grid data to destination grid

	 * @param o source object reference
	 */
	 cfdGrid &operator=(const cfdGrid &o);


	/** Destructor
	 * ---
	 * Inline Destructor releases the memory of two-dimensional array
	 */
	~cfdGrid(){	delete[] body;	}


	/** Method: TridiagonalSolve
	 * ---
	 * Solves a tridiagonal grid with TDMA algorithm
	 */
	void TridiagonalSolve();

	/** Method: GElimSolve
	 * ---
	 * Solves a grid with Gauss-Elimination algorithm WITHOUT partial-pivoting
	 */
	void GElimSolve();

	/** Overloaded Method: toArray
	 * ---
	 * takes a pointer to a sequentially stored array as destination to copy the grid data
	 * @param ar array stored sequentially in memory. Most compilers prefer the other way when 
	 *			 declaring a two-d array and save it as pointers pointing to another one-d array.
	 */
	void toArray(double*ar);


	/** Overloaded Method: toArray
	 * ---
	 * takes a pointer to an array(array of pointers to 1-d array) as destination to copy the grid data
	 * @param ar array stored as pointers pointing to another one-d array of doubles. Most compilers prefer
				 prefer this way when a two-d array is declared.
	 */
	void toArray(double**ar);

	/** Overloaded Method: toGrid
	 * ---
	 * takes a pointer to a sequentially stored array as source to copy to the grid
	 * @param ar array stored sequentially in memory. Most compilers prefer the other way when 
	 *			 declaring a two-d array and save it as pointers pointing to another one-d array.
	 */
	void toGrid(double*ar);

	/** Overloaded Method: toArray
	 * ---
	 * takes a pointer to an array(array of pointers to 1-d array) as a source to copy to the grid
	 * @param ar array stored as pointers pointing to another one-d array of doubles. Most compilers prefer
				 prefer this way when a two-d array is declared.
	 */
	void toGrid(double**ar);

	/** Method: fillGrid
	 * ---
	 * fills grid points with given mathematical expression.
	 * @param	fxy	is a mathematical expression which may have 'x' and 'y' as variables.
					The values of x and y will be calculated by x=(index in x)*dx & y=(index in y)*dy
	 * @param	dx	used in x value evaluation in fx
	 * @param	dy	used in y value evaluation in fx
	 */
	void fillGrid(char* fxy,double dx=0,double dy=0);

	/** Method: fillBoundary
	 * ---
	 * fills boundary points with given mathematical expressions.
	 * @param	bound	is an array of four mathematical expression which can have only 'x' as variable.
						boundary edges are numbered clockwise and stored starting from left boundary.
						eg. left boundary expression is at 0 index and x is calculated by x=(index in y)*dy
							top boundary expression is at 1 index and x is caluculated by x=(index in x)*dx
							and so on for the other two boundaries
	 * @param	dx	used in top and bottom boundary values in bound[1] and bound[3], respectively
	 * @param	dy	used in left and right boundary values in bound[0] and bound[2], respectively
	 */
	void fillBoundary(char bound[4][128],double dx=0,double dy=0);


	/** Method: Bandsolve
	 * ---
	 * TODO: 
	 * Solves a Band-grid
	 * @param	bandwidth	bandwidth of the grid
	 */
	void Bandsolve(int bandwidth);
	
	/**	Getter Method for x
	 */
	int getX(){return x;}
	
	/**	Getter Method for y
	 */
	int getY(){return y;}
private:
	int x,y;
public:
	double** body;
};

